<?php
// +----------------------------------------------------------------------
// | 双擎码防伪溯源系统 [ 致力于通过产品和服务，帮助商家开启标准化全链路商品溯源 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009~2024 https://www.sqm.la All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 双擎科技 <yjw@sqm.la>
// +----------------------------------------------------------------------
namespace think\admin\service;

use think\admin\service\RuntimeService;
use think\admin\Exception;
use think\admin\Service;

/**
 * 机器人 webhook推送
 * Class robotService
 * @package think\admin\service
 * Date 2024/9/6 上午8:45
 */
class robotService extends Service
{
    /**
     * 机器人消息推送
     * @param string $platform
     * @param string $webhookUrl
     * @param $messageContent
     * @param string $messageType
     * @param array $at
     * @return bool
     * @throws Exception
     */
    public static function robotSend(string $platform, string $webhookUrl, $messageContent, string $messageType = 'text', array $at = []): bool
    {
        // 开发模式下不发送消息推送
        if(RuntimeService::isDebug()){
            return false;
        }else try {
            $response = self::sendNotification($platform, $webhookUrl, $messageContent, $messageType, $at);
            // 检查发送成功的条件
            if ((isset($response['errcode']) && $response['errcode'] === 0) ||
                (isset($response['StatusCode']) && $response['StatusCode'] === 0)) {
                return true;
            } else {
                return false;
            }
        } catch (\Exception $e) {
            throw new Exception($e->getMessage(), $e->getCode());
        }

    }
    /**
     * 机器人通知 钉钉DingTalk
     * 钉钉：支持通过 atUserIds、atMobiles 和 isAtAll 来@用户。
     * 飞书：不支持通过 Webhook @用户，通常需要通过应用接口实现。
     * 企业微信：支持通过 mentioned_list 和 mentioned_mobile_list 来@用户。
     * @param string $platform 平台：dingtalk，feishu,wechat
     * @param string $webhookUrl
     * @param $messageContent
     * @param string $messageType
     * @param array $at
     * @return bool|string
     * @throws Exception
     */
    public static function sendNotification(string $platform, string $webhookUrl, $messageContent, string $messageType = 'text', array $at = []): bool|string
    {
        $data = [];
        /*
         * // 示例调用
         * try {
         * $platform = 'dingtalk';
         * $webhookUrl = 'YOUR_DINGTALK_WEBHOOK_URL';
         * $messageContent = "Hello, this is a test message!";
         * $messageType = 'text';
         * $at = [
         * 'atUserIds' => ['user001', 'user002'],
         * 'atMobiles' => ['15xxx', '18xxx'],
         * 'isAtAll' => false
         * ];
         *
         * $response = NotificationSender::sendNotification($platform, $webhookUrl, $messageContent, $messageType, $at);
         * echo $response;
         * } catch (Exception $e) {
         * echo 'Error: ' . $e->getMessage();
         * }
         */
        switch ($platform) {
            case 'dingtalk':
                switch ($messageType) {
                    case 'text':
                        $data = [
                            "msgtype" => "text",
                            "text" => [
                                "content" => $messageContent
                            ],
                            "at" => [
                                "atUserIds" => $at['atUserIds'] ?? [],
                                "atMobiles" => $at['atMobiles'] ?? [],
                                "isAtAll" => $at['isAtAll'] ?? false
                            ]
                        ];
                        break;
                    case 'link':
                        $data = [
                            "msgtype" => "link",
                            "link" => [
                                "text" => $messageContent['text'],
                                "title" => $messageContent['title'],
                                "picUrl" => $messageContent['picUrl'],
                                "messageUrl" => $messageContent['messageUrl']
                            ]
                        ];
                        break;
                    case 'markdown':
                        $data = [
                            "msgtype" => "markdown",
                            "markdown" => [
                                "title" => $messageContent['title'],
                                "text" => $messageContent['text']
                            ],
                            "at" => [
                                "atUserIds" => $at['atUserIds'] ?? [],
                                "atMobiles" => $at['atMobiles'] ?? [],
                                "isAtAll" => $at['isAtAll'] ?? false
                            ]
                        ];
                        break;
                    default:
                        throw new Exception("DingTalk不支持的消息类型: $messageType");
                }
                break;

            case 'feishu':
                // 飞书不支持通过 Webhook @用户，通常需要在应用内实现。
                switch ($messageType) {
                    case 'text':
                        $data = [
                            "msg_type" => "text",
                            "content" => [
                                "text" => $messageContent
                            ]
                        ];
                        break;
                    case 'post':
                        $data = [
                            "msg_type" => "post",
                            "content" => [
                                "post" => $messageContent
                            ]
                        ];
                        break;
                    case 'image':
                        $data = [
                            "msg_type" => "image",
                            "content" => [
                                "image_key" => $messageContent['image_key']
                            ]
                        ];
                        break;
                    default:
                        throw new Exception("Feishu不支持的消息类型: $messageType");
                }
                break;

            case 'wechat':
                switch ($messageType) {
                    case 'text':
                        $data = [
                            "msgtype" => "text",
                            "text" => [
                                "content" => $messageContent,
                                "mentioned_list" => $at['mentioned_list'] ?? [],
                                "mentioned_mobile_list" => $at['mentioned_mobile_list'] ?? []
                            ]
                        ];
                        break;
                    case 'image':
                        $data = [
                            "msgtype" => "image",
                            "image" => [
                                "base64" => $messageContent['base64'],
                                "md5" => $messageContent['md5']
                            ]
                        ];
                        break;
                    case 'markdown':
                        $data = [
                            "msgtype" => "markdown",
                            "markdown" => [
                                "content" => $messageContent
                            ]
                        ];
                        break;
                    case 'news':
                        $data = [
                            "msgtype" => "news",
                            "news" => [
                                "articles" => $messageContent['articles']
                            ]
                        ];
                        break;
                    default:
                        throw new Exception("WeChat不支持的消息类型: $messageType");
                }
                break;

            default:
                throw new Exception("不支持的平台: $platform");
        }

        $dataString = json_encode($data);

        $ch = curl_init($webhookUrl);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($dataString)
        ]);

        $result = curl_exec($ch);

        if ($result === false) {
            throw new Exception('cURL Error: ' . curl_error($ch));
        }

        curl_close($ch);

        return $result;
    }

}